#ifndef ANALYZE_TRAVERSAL_H
#define ANALYZE_TRAVERSAL_H
#include "StructWrapper.h"

class analyzeTraversal : public AstPrePostProcessing {
    public:
        analyzeTraversal(FunctionContext **fc, int n); 
        analyzeTraversal(); 
        virtual void preOrderVisit(SgNode *node);
        virtual void postOrderVisit(SgNode *node);
        void print();
        void gatherAllAliases();
        void removeDuplicates();
        int num_globals() { return n_globals; }
        VariableWrapper **get_globals() { return globals; }
        void setFunctions(FunctionContext **set_all_functions, int set_n_functions) { all_functions = set_all_functions; n_functions = set_n_functions; }
        SgDeclarationStatement *resolveSymbol(SgVarRefExp *ref);
        Reference *generateReference(SgExpression *arg, SgVarRefExp **var, SgDeclarationStatement **val_passed, VariableWrapper **var_passed);
        void appendReads(Reference **refs, int n);
        FunctionContext *getCurrentFunction() { return current_function; }
    private:
        void init(FunctionContext **fc, int N);
        FunctionContext *current_function;
        int current_function_index;
        StructWrapper *current_struct;
        int current_struct_index;
        FunctionContext **all_functions;
        int n_functions;

        VariableWrapper **globals;
        //SgVariableDeclaration **globals;
        int n_globals;

        SgScopeStatement **scope_stack;
        int scope_depth;

        StructWrapper **structs;
        int n_structs;

        void appendWrites(Reference **refs, int n);
        int addFunction(SgFunctionDeclaration *decl);
        VariableWrapper *addLocalVar(SgVariableDeclaration *decl);
        void addGlobal(SgVariableDeclaration *global);
        void addStruct(SgClassDefinition *struct_def);
        int findFunction(FullFunctionCall *call);
        int findFunction(SgFunctionDefinition *def);
        int findFunction(SgFunctionDeclaration *decl);
        int findFunction(string name);
        int contains(Reference **arr, Reference *val, int N);
        int duplicate(Reference **arr, Reference *find, int N);
};



#endif
